home *** CD-ROM | disk | FTP | other *** search
/ GameWare Collection / GameWare Collection (CMS Software) (1993).iso / games / s_games / spaceinv.pas < prev    next >
Pascal/Delphi Source File  |  1990-09-29  |  16KB  |  580 lines

  1. {$C-}
  2. PROGRAM SpaceInv;
  3.  
  4. {
  5.                       VERSION 5.1 -- By Timothy Campbell
  6.  
  7. }
  8.  
  9.  
  10. TYPE
  11.   Line       = STRING[80];
  12.   Sprite     = STRING[7];
  13.   SpriteType = (Base,Missle,Ufo1,Bomb1,Ufo2,Bomb2,Ufo3,Bomb3,Ufo4,Bomb4,
  14.                 Ufo5,Bomb5,Ufo6,Bomb6);
  15.   Switch     = (Off,On);
  16.  
  17.  
  18. CONST
  19.   Blanks    = '       ';
  20.   DelayAdj  = 3;
  21.   DelayInit = 70;
  22.   NumSyms   = 13;
  23.   Shields   = ' '#176#177#178#219;
  24.   Sprites   : ARRAY [0..NumSyms] OF Sprite =
  25.             ( #213#209#202#209#184,
  26.               #024,
  27.               #017#016#174#153#175#017#016,
  28.               #079,
  29.               #060#243#234#242#062,
  30.               #147,
  31.               #174#017#016#175,
  32.               #015,
  33.               #017#001#016,
  34.               #157,
  35.               #199#002#182,
  36.               #031,
  37.               #233,
  38.               'v'                      );
  39.   Explode   : ARRAY [0..5] OF Sprite =
  40.             ( #219#219#219#219#219#219#219,
  41.               #178#178#178#178#178#178#178,
  42.               #177#177#177#177#177#177#177,
  43.               #176#176#176#176#176#176#176,
  44.               '- - - - -',
  45.               '       '               );
  46.  
  47. VAR
  48.   Active    : ARRAY[0..NumSyms] OF BOOLEAN;
  49.   ActiveCnt : BYTE;
  50.   Beat      : INTEGER;
  51.   BombType  : SpriteType;
  52.   DelayTime : INTEGER;
  53.   Explosion : BYTE;
  54.   InChar    : CHAR;
  55.   MisX      : BYTE;
  56.   MisY      : BYTE;
  57.   Move      : ARRAY[0..NumSyms] OF INTEGER;
  58.   MoveUfo6  : BYTE;
  59.   Noise     : BOOLEAN;
  60.   NowX      : BYTE;
  61.   NowY      : BYTE;
  62.   ShieldLev : BYTE;
  63.   RandomMod : BYTE;
  64.   Score     : INTEGER;
  65.   ShieldCnt : INTEGER;
  66.   SpriteLen : BYTE;
  67.   SprX      : BYTE;
  68.   SprY      : BYTE;
  69.   Thingy    : INTEGER;
  70.   Tick      : BYTE;
  71.   UfoTick   : BYTE;
  72.   UfoType   : SpriteType;
  73.   WX,WY     : BYTE;
  74.   XPosn     : ARRAY[0..NumSyms] OF BYTE;
  75.   YPosn     : ARRAY[0..NumSyms] OF BYTE;
  76.  
  77. FUNCTION Divis(Dv1,Dv2 : INTEGER) : BOOLEAN;
  78. BEGIN
  79.   IF (Dv1 DIV Dv2) * Dv2 = Dv1
  80.   THEN Divis := TRUE
  81.   ELSE Divis := FALSE;
  82. END;
  83.  
  84. PROCEDURE Ce(CIn : Line);
  85. BEGIN
  86.   GOTOXY(((80 - LENGTH(Cin)) DIV 2),WHEREY);
  87.   WRITELN(CIn);
  88. END;
  89.  
  90. FUNCTION Sz(SIn : Line) : Line;
  91. BEGIN
  92.   Sz := Copy((SIn + Blanks),1,7);
  93. END;
  94.  
  95. PROCEDURE DawdleJet;
  96. VAR
  97.   BanLoop : BYTE;
  98.   Mult    : INTEGER;
  99. BEGIN
  100.   Mult   := 1;
  101.   Thingy := 100;
  102.   REPEAT
  103.     Thingy := Thingy + Mult;
  104.     IF Thingy > 4000 THEN Mult := -1;
  105.     IF Thingy <  100 THEN Mult := 1;
  106.     FOR BanLoop := 1 TO 5 DO
  107.     BEGIN
  108.       SOUND(Thingy);
  109.       DELAY(1);
  110.       SOUND(4200-Thingy);
  111.       DELAY(1+RANDOM(8));
  112.     END;
  113.   UNTIL KEYPRESSED;
  114.   READ(KBD,InChar);
  115.   NOSOUND;
  116. END;
  117.  
  118. PROCEDURE DawdleNoise;
  119. BEGIN
  120.   REPEAT
  121.     SOUND(200+RANDOM(3000));
  122.     DELAY(1+RANDOM(8));
  123.     NOSOUND;
  124.     DELAY(1+RANDOM(50));
  125.   UNTIL KEYPRESSED;
  126.   READ(KBD,InChar);
  127.   NOSOUND;
  128. END;
  129.  
  130. PROCEDURE Banner;
  131. BEGIN
  132.   CLRSCR;
  133.   Ce('┌───────────────────────────────────────────────────────┬──────────────────┐');
  134.   Ce('│  Pinnacle  Software''s  Space  Investors  Video  Game  │     SPACEINV     │');
  135.   Ce('├───────────────────────────────────────────────────────┴──────────────────┤');
  136.   Ce('│  C O P Y R I G H T  (C)  1986   BY   P I N N A C L E    S O F T W A R E  │');
  137.   Ce('├──────────────────────────────────────────────────────────────────────────┤');
  138.   Ce('│ This program may be  freely distributed  so long as it is distributed in │');
  139.   Ce('│ its complete and unaltered form,  including this notice.                 │');
  140.   Ce('├──────────────────────────────────────────────────────────────────────────┤');
  141.   Ce('├────────────     ╦══╗ ═╦═ ╦═╗ ╔ ╦═╗ ╔ ╔══╗ ╔══╗ ╦    ╦══╗     ────────────┤');
  142.   Ce('├────────────     ╠══╝  ║  ║ ║ ║ ║ ║ ║ ╠══╣ ║    ║    ╠═       ────────────┤');
  143.   Ce('├────────────     ╩    ═╩═ ╝ ╚═╝ ╝ ╚═╝ ╩  ╩ ╚══╝ ╩══╝ ╩══╝     ────────────┤');
  144.   Ce('├────────────     ╔══╗ ╔══╗ ╦══╗ ╔═╦═╗ ╗   ╔ ╔═╗ ╦══╗ ╦══╗     ────────────┤');
  145.   Ce('├────────────     ╚══╗ ║  ║ ╠═     ║   ║ ║ ║ ╠═╣ ╠═╦╝ ╠═       ────────────┤');
  146.   Ce('├────────────     ╚══╝ ╚══╝ ╩      ╩   ╚═╩═╝ ╩ ╩ ╩ ╚╝ ╩══╝     ────────────┤');
  147.   Ce('├────────────     Post Office Box 163 Cartierville Station     ────────────┤');
  148.   Ce('├────────────     Cartierville,  Quebec,  Canada,  H4K 2J5     ────────────┤');
  149.   Ce('└──────────────────────────────────────────────────────────────────────────┘');
  150.   WRITELN;
  151.   Ce('Want to run a new kind of BBS?   Send us $35 and we''ll send you your copy of');
  152.   Ce('one of Montreal''s  top BBS''s:  the Pyroto Mountain  BBS/Game system.  You''ll');
  153.   Ce('need a 128K IBM-PC with two diskette drives and a "smart" modem.            ');
  154.   WRITELN;
  155.   Ce('PRESS A KEY TO CONTINUE');
  156.   DawdleJet;
  157.   CLRSCR;
  158.   Ce('PINNACLE SOFTWARE PRESENTS');
  159.   Ce('┌─-─=─=─=─=─=─=─=─=─=─=─=─=─=─=─=─-─┐');
  160.   Ce(')   S P A C E   I N V E S T O R S   (');
  161.   Ce('└─-─=─=─=─=─=─=─=─=─=─=─=─=─=─=─=─-─┘');
  162.   WRITELN;
  163.   Ce('Watch out for ...');
  164.   WRITELN;
  165.   Ce('THE MOTHER SHIP   ' + Sz(Sprites[ORD(Ufo1)]));
  166.   Ce('THE BATTLE POD    ' + Sz(' '+Sprites[ORD(Ufo2)]));
  167.   Ce('THE DRIFTER       ' + Sz(' '+Sprites[ORD(Ufo3)]));
  168.   Ce('THE HARASSER      ' + Sz('  '+Sprites[ORD(Ufo4)]));
  169.   Ce('THE DARE-DEVIL    ' + Sz('  '+Sprites[ORD(Ufo5)]));
  170.   Ce('THE OBSERVER      ' + Sz('   '+Sprites[ORD(Ufo6)]));
  171.   WRITELN;
  172.   Ce('    The keys are used as follows...                 ');
  173.   Ce('    F and J ..... move base left and right          ');
  174.   Ce('    E and I ..... either key will stop base movement');
  175.   Ce('    Spacebar .... fires a missle                    ');
  176.   Ce('    - (minus) ... toggles sound on and off          ');
  177.   Ce('    P ........... pauses the game                   ');
  178.   Ce('    ESC ......... exits the game (you coward!)      ');
  179.   WRITELN;
  180.   Ce('*** PRESS A KEY TO START ***');
  181.   DawdleNoise;
  182. END;
  183.  
  184. PROCEDURE ShowScore;
  185. BEGIN
  186.   GOTOXY(1,25);
  187.   WRITE('SCORE: ',Score,'   SHIELD LEVEL: ',
  188.   Copy(Shields,1,ShieldLev),'  ');
  189. END;
  190.  
  191. PROCEDURE Cursor(CCtl : Switch);
  192. TYPE
  193.   regpack =
  194.   RECORD
  195.     ax,bx,cx,dx,bp,di,si,ds,es,flags: INTEGER;
  196.   END;
  197. VAR
  198.   recpack : regpack;
  199. BEGIN
  200.   WITH recpack DO
  201.   BEGIN
  202.     ax := $0100;
  203.     IF CCtl = On
  204.     THEN cx := $0CCD
  205.     ELSE cx := $FFFF;
  206.   END;
  207.   INTR($10,recpack);
  208. END;
  209.  
  210. PROCEDURE BEEP(Tone : INTEGER);
  211. BEGIN
  212.   IF Noise THEN SOUND(Tone);
  213. END;
  214.  
  215. PROCEDURE SetPosn(IntST : SpriteType; IntX, IntY : BYTE);
  216. BEGIN
  217.   IF ((IntX = 0) AND (IntY = 0)) AND (Active[ORD(IntST)] = TRUE) THEN
  218.   BEGIN
  219.     Active[ORD(IntST)] := FALSE;
  220.     ActiveCnt     := ActiveCnt - 1;
  221.   END;
  222.   IF ((IntX > 0) AND (IntY > 0)) THEN
  223.   BEGIN
  224.     IF Active[ORD(IntST)] = FALSE THEN
  225.     BEGIN
  226.       Active[ORD(IntST)] := TRUE;
  227.       IF (RANDOM(100) < 33) AND (IntST IN [Ufo1,Ufo2,Ufo3,Ufo4,Ufo5,Ufo6]) THEN
  228.       BEGIN
  229.         Move[ORD(IntST)]   := -1;
  230.         IntX := 80 - LENGTH(Sprites[ORD(IntST)]) - 1;
  231.       END
  232.       ELSE Move[ORD(IntST)]   := 1;
  233.       ActiveCnt          := ActiveCnt + 1;
  234.     END;
  235.     XPosn[ORD(IntST)]  := IntX;
  236.     YPosn[ORD(IntST)]  := IntY;
  237.   END;
  238. END;
  239.  
  240. PROCEDURE FindXY(FndST : SpriteType);
  241. BEGIN
  242.   NowX := XPosn[ORD(FndST)];
  243.   NowY := YPosn[ORD(FndST)];
  244. END;
  245.  
  246. {======= MOVEMENT =======}
  247.  
  248. PROCEDURE MoveX(SprTyp : SpriteType);
  249. VAR
  250.   OutSprite : STRING[9];
  251.   XGo       : BYTE;
  252.   YGo       : BYTE;
  253. BEGIN
  254.   OutSprite := Sprites[ORD(SprTyp)];
  255.   SpriteLen := Length(OutSprite);
  256.   FindXY(SprTyp);
  257.   IF SprTyp <> Base THEN
  258.   BEGIN
  259.     IF (RANDOM(1000) < SpriteLen * 5)
  260.     OR ((SprTyp = Ufo6) AND (RANDOM(100) < 5)) THEN
  261.     BEGIN
  262.       IF NowX < XPosn[ORD(Base)] THEN Move[ORD(SprTyp)] := 1;
  263.       IF NowX > XPosn[ORD(Base)] THEN Move[ORD(SprTyp)] := -1;
  264.     END;
  265.   END;
  266.   XGo := NowX + Move[ORD(SprTyp)];
  267.   IF XGo < 1 THEN XGo := 1;
  268.   IF XGo + SpriteLen > 80 THEN XGo := 80 - SpriteLen;
  269.   SetPosn(SprTyp,XGo,NowY);
  270.   IF SprTyp <> Base THEN
  271.   BEGIN
  272.     IF RANDOM(120) < ORD(SprTyp) THEN
  273.     BEGIN
  274.       OutSprite := COPY(Blanks,1,SpriteLen);
  275.       IF RANDOM(100) < 33
  276.       THEN YGo := NowY - 1
  277.       ELSE YGo := NowY + 1;
  278.       IF YGo < 1  THEN YGo := 1;
  279.       IF YGo > 18 THEN YGo := 17;
  280.       GOTOXY(NowX,YGo);
  281.       WRITE(Sprites[ORD(SprTyp)]);
  282.       FOR Thingy := 40 DOWNTO 5 DO BEEP(Thingy * 100);
  283.       SetPosn(SprTyp,NowX,YGo);
  284.     END;
  285.   END;
  286.   IF (XGo > 1) AND (Move[ORD(SprTyp)] > 0) THEN
  287.   BEGIN
  288.     XGo := XGo - 1;
  289.     OutSprite := ' ' + OutSprite;
  290.   END;
  291.   IF (XGo < 80) AND (Move[ORD(SprTyp)] < 0) THEN OutSprite := OutSprite + ' ';
  292.   GOTOXY(XGo,NowY);
  293.   WRITE(OutSprite);
  294. END;
  295.  
  296. PROCEDURE CheckBoom(BWep, Wnme : SpriteType; MisX, MisY : BYTE);
  297.   BEGIN
  298.     FindXY(Wnme);
  299.     SpriteLen := LENGTH(Sprites[ORD(Wnme)]);
  300.     IF (MisX IN [NowX .. (NowX + SpriteLen-1)]) AND (MisY = NowY)
  301.     AND Active[ORD(Wnme)]
  302.     THEN
  303.     BEGIN
  304.       FOR Explosion := 0 TO 5 DO
  305.       BEGIN
  306.         FOR Thingy := 1 TO (SpriteLen * 10) DO
  307.         BEGIN
  308.           DELAY(1);
  309.           BEEP(500+RANDOM(4000 - Thingy * 50));
  310.         END;
  311.         GOTOXY(NowX,NowY);
  312.         WRITE(Copy(Explode[Explosion],1,SpriteLen));
  313.       END;
  314.       IF BWep = Missle THEN
  315.       BEGIN
  316.         Score := Score + (14 - ORD(Wnme)) * 10;
  317.         SetPosn(Wnme,0,0);
  318.         SetPosn(Missle,0,0);
  319.       END
  320.       ELSE
  321.       BEGIN
  322.         IF Divis(Beat,3)
  323.         THEN Move[ORD(PRED(BWep))] := Move[ORD(PRED(Bwep))] * -1;
  324.         Score := Score - 100;
  325.         IF Score < 0 THEN Score := 0;
  326.         SetPosn(BWep,0,0);
  327.         ShieldLev   := ShieldLev - 1;
  328.       END;
  329.       ShowScore;
  330.     END;   { Weapon hit enemy }
  331.   END;     { CheckBoom }
  332.  
  333.  
  334. PROCEDURE MoveWeapon(WType : SpriteType);
  335.   BEGIN
  336.     IF Active[ORD(WType)] THEN
  337.     BEGIN
  338.       FindXY(WType);
  339.       GOTOXY(NowX,NowY);
  340.       WRITE(' ');
  341.       IF (PRED(WType) IN [Ufo1,Ufo2]) THEN
  342.       BEGIN
  343.         {-- Smart Bomb --}
  344.         IF Divis(Beat,ORD(WType)*3)
  345.         AND Active[ORD(PRED(WType))]
  346.         THEN
  347.         BEGIN
  348.           FOR Thingy := 1 TO (Score DIV 1000) DO
  349.           BEGIN
  350.             IF XPosn[ORD(Base)] > NowX THEN NowX := NowX + 1;
  351.             IF XPosn[ORD(Base)] < NowX THEN NowX := NowX - 1;
  352.           END;
  353.         END;
  354.       END;
  355.       IF WType = Missle
  356.       THEN NowY := NowY - 1
  357.       ELSE NowY := NowY + 1;
  358.       IF NOT (NowY IN [1..24])
  359.       THEN SetPosn(WType,0,0)
  360.       ELSE
  361.       BEGIN
  362.         BEEP(500+(ORD(WType)*RANDOM(200))+(25-NowY)*100);
  363.         GOTOXY(NowX,NowY);
  364.         WRITE(Sprites[ORD(WType)]);
  365.         SetPosn(WType,NowX,NowY);
  366.         WX := NowX;
  367.         WY := NowY;
  368.         IF WType = Missle
  369.         THEN
  370.         BEGIN
  371.           CheckBoom(WType,Ufo1,WX,WY);
  372.           CheckBoom(WType,Ufo2,WX,WY);
  373.           CheckBoom(WType,Ufo3,WX,WY);
  374.           CheckBoom(WType,Ufo4,WX,WY);
  375.           CheckBoom(WType,Ufo5,WX,WY);
  376.           CheckBoom(WType,Ufo6,WX,WY);
  377.         END
  378.         ELSE CheckBoom(WType,Base,WX,WY);
  379.       END;     { Weapon on screen }
  380.     END;       { Specified weapon active }
  381.   END;
  382.  
  383.  
  384. PROCEDURE MoveUfo(UfoST : SpriteType);
  385.   BEGIN
  386.     {--- Ufo Movement ---}
  387.     IF Active[ORD(UfoST)] THEN
  388.     BEGIN
  389.       IF (Tick IN [1..7]) THEN Move[ORD(UfoST)] := Move[ORD(UfoST)] * -1;
  390.       UfoTick := UfoTick + RANDOM(3);
  391.       IF UfoTick > 99 THEN UfoTick := 0;
  392.       IF Divis(UfoTick,(ORD(UfoST) DIV 2)) THEN
  393.       BEGIN
  394.         MoveX(UfoST);
  395.         BEEP(ORD(UfoST) * 300);
  396.         DELAY(1);
  397.         SprX := NowX;
  398.         FindXY(Base);
  399.         {--- Drop a bomb? ---}
  400.         IF (NOT Active[ORD(UfoST)+1])        { Not if one already dropping }
  401.         AND
  402.         (((Beat < LENGTH(Sprites[ORD(UfoST)])*10) AND
  403.         (SprX IN [NowX-1,NowX,NowX+1]))      { Bigger Ufo's use good shots }
  404.         OR
  405.         (Beat < (Score DIV 20)))             { 100% chance at score 2000 }
  406.         AND (NOT ((UfoST = Ufo6) AND (RANDOM(1000) < 995)))  { Rare bomber }
  407.         THEN
  408.         BEGIN
  409.           BEEP(1200);
  410.           FindXY(UfoST);
  411.           SetPosn(SUCC(UfoST),
  412.           (NowX+(LENGTH(Sprites[ORD(UfoST)]) DIV 2)),
  413.           NowY+1);
  414.         END;
  415.         SpriteLen := LENGTH(Sprites[ORD(UfoST)]);
  416.         FindXY(UfoST);
  417.         IF (NowX = 1) OR ((NowX + SpriteLen) > 79) THEN
  418.         BEGIN
  419.           SetPosn(UfoST,0,0);
  420.           BEEP(3500);
  421.           GOTOXY(NowX,NowY);
  422.           WRITE(Copy(Blanks,1,SpriteLen));
  423.         END;
  424.       END;   { Ufo Movement }
  425.     END;     { Ufo Introduction }
  426.   END;       { MoveUfo }
  427.  
  428. {======= INITIALIZATION =======}
  429.  
  430.  
  431. PROCEDURE StartUp;
  432.   VAR
  433.     Loop1    : BYTE;
  434.  
  435.   BEGIN
  436.     Banner;
  437.     CLRSCR;
  438.     ActiveCnt := 0;
  439.     Beat      := 0;
  440.     InChar    := '?';
  441.     Noise     := TRUE;
  442.     RandomMod := 0;
  443.     Score     := 0;
  444.     ShieldCnt := 0;
  445.     ShieldLev := 5;
  446.     UfoTick   := 0;
  447.     FOR Loop1 := 0 TO NumSyms DO
  448.     BEGIN
  449.       Active[Loop1] := FALSE;
  450.       Move[Loop1]   := 0;
  451.       XPosn[Loop1]  := 0;
  452.       YPosn[Loop1]  := 0;
  453.     END;
  454.     SetPosn(Base,39,24);
  455.   END;
  456.  
  457.  
  458. {======= MAINLINE =======}
  459.  
  460.  
  461. BEGIN
  462.   StartUp;
  463.   Cursor(Off);
  464.   ShowScore;
  465.   REPEAT
  466.     IF (Score DIV 1000 > ShieldCnt) AND (ShieldLev < 5)
  467.     THEN
  468.     BEGIN
  469.       ShieldLev := ShieldLev + 1;
  470.       ShieldCnt := ShieldCnt + 1;
  471.       ShowScore;
  472.     END;
  473.     {--- Beats and Ticks ---}
  474.     Tick := RANDOM(50) + RandomMod;
  475.     IF InChar = 'F' THEN RandomMod := RandomMod + 1;
  476.     IF RandomMod > 50 THEN RandomMod := 0;
  477.     Beat := Beat + 1;
  478.     IF Beat > 100 THEN Beat := 0;
  479.     {--- Commands ---}
  480.     IF KEYPRESSED THEN
  481.     BEGIN
  482.       BEEP(500);
  483.       READ(KBD,InChar);
  484.       InChar := UPCASE(InChar);
  485.       CASE InChar OF
  486.       '-' : BEGIN
  487.               Noise := NOT Noise;
  488.               NOSOUND;
  489.             END;
  490.       'F' : Move[ORD(Base)] := -1;
  491.       'J' : Move[ORD(Base)] := 1;
  492.       'I' : Move[ORD(Base)] := 0;
  493.       'E' : Move[ORD(Base)] := 0;
  494.       ' ' : BEGIN
  495.               Score := Score - 1;
  496.               IF Score < 0 THEN Score := 0;
  497.               IF Active[ORD(Missle)] THEN
  498.               BEGIN
  499.                 FindXY(Missle);
  500.                 GOTOXY(NowX,NowY);
  501.                 WRITE(' ');
  502.               END;
  503.               BEEP(2200);
  504.               FindXY(Base);
  505.               SetPosn(Missle,NowX+3,23);
  506.             END;  { SPACE CASE }
  507.       'P' : BEGIN
  508.               NOSOUND;
  509.               GOTOXY(70,1);
  510.               WRITE('*PAUSED*');
  511.               REPEAT UNTIL KEYPRESSED;
  512.               READ(KBD,InChar);
  513.               InChar := '?';
  514.               GOTOXY(70,1);
  515.               WRITE('        ');
  516.             END;
  517.       END;        { CASE }
  518.   END;
  519.   {--- Timing Delay ---}
  520.   DelayTime := DelayInit - ActiveCnt * DelayAdj;
  521.   DelayTime := DelayTime - (Score DIV 250);
  522.   IF DelayTime < 0 THEN DelayTime := 0;
  523.   IF Divis(Beat,10) THEN BEEP(150);
  524.   DELAY(DelayTime);
  525.   {--- Base Movement ---}
  526.   MoveX(Base);
  527.   IF (Divis(Beat,2)) AND (Move[ORD(Base)] <> 0)
  528.   THEN BEEP(1000+NowX*10)
  529.   ELSE NOSOUND;
  530.   {--- Weapon Movement ---}
  531.   MoveWeapon(Missle);
  532.   IF ShieldLev > 0 THEN
  533.   BEGIN
  534.     {--- Bring in a new UFO? ---}
  535.     UfoType := Ufo1;
  536.     IF Beat > 10 THEN UfoType := Ufo2;
  537.     IF Beat > 25 THEN UfoType := Ufo3;
  538.     IF Beat > 50 THEN UfoType := Ufo4;
  539.     IF Beat > 75 THEN UfoType := Ufo5;
  540.     IF Beat > 90 THEN UfoType := Ufo6;
  541.     IF ((RANDOM(1000) <= (Score DIV 100) + 15)
  542.     OR (ActiveCnt <= 2))
  543.     AND (Active[ORD(UfoType)] = FALSE)
  544.     THEN SetPosn(UfoType,1,ORD(UfoType) + RANDOM(5));
  545.     MoveWeapon(Bomb1);
  546.     MoveUfo(Ufo1);
  547.     MoveWeapon(Bomb2);
  548.     MoveUfo(Ufo2);
  549.     MoveWeapon(Bomb3);
  550.     MoveUfo(Ufo3);
  551.     MoveWeapon(Bomb4);
  552.     MoveUfo(Ufo4);
  553.     MoveWeapon(Bomb5);
  554.     MoveUfo(Ufo5);
  555.     MoveWeapon(Bomb6);
  556.     FOR MoveUfo6 := 1 to 5 DO
  557.     BEGIN
  558.       MoveUfo(Ufo6);
  559.     END;
  560.   END;              { ShieldLev > 0 }
  561.   IF ShieldLev <= 0 THEN
  562.   BEGIN
  563.     CLRSCR;
  564.     WRITELN;
  565.     WRITELN('             G A M E   O V E R  --  Score: ',Score);
  566.     WRITELN;
  567.     IF Noise THEN
  568.     BEGIN
  569.       FOR Thingy := 4 DOWNTO 1 DO
  570.       BEGIN
  571.         SOUND(500+Thingy * 1000);
  572.         DELAY(500+RANDOM(5-Thingy)*80);
  573.       END;
  574.     END;
  575.   END;
  576.   UNTIL (InChar = #27) OR (ShieldLev = 0);
  577.   NOSOUND;
  578.   Cursor(On);
  579. END.
  580.